-- Instructions, Registers and Miscellaneous Tables --

  -- REFERENCE TO LASM: gen2operandCode(noImmbyte, immbyte, imm3bits)

  -- Coded bytes convention:
  -- Use comma-separated list for multibytes
  -- All quoted bytes are treated as hexadecimal
  -- If not quoted, it would be treated as decimal value
  -- (I s i) means an integer represented in s bytes.  Little Endian for Intel
  -- If there is a plus sign before, offset is applied to it

  -- Refer Emit.CodedBytes in Emitter.sl


-- No Operand Instructions Code Table --

  -- Instruction.NoOp <inst> <cc> generates: cc
Instruction.NoOp	"AAA"	(+'37') #
Instruction.NoOp	"AAD"	('D5',+'0A') #
Instruction.NoOp	"AAM"	('D4',+'0A') #
Instruction.NoOp	"AAS"	(+'3F') #
Instruction.NoOp	"CBW"	('66',+'98') #
Instruction.NoOp	"CDQ"	(+'99') #
Instruction.NoOp	"CLC"	(+'F8') #
Instruction.NoOp	"CLD"	(+'FC') #
Instruction.NoOp	"CLI"	(+'FA') #
Instruction.NoOp	"CLTS"	('0F',+'06') #
Instruction.NoOp	"CMC"	(+'F5') #
Instruction.NoOp	"CMPSB"	(+'A6') #
Instruction.NoOp	"CMPSD"	(+'A7') #
Instruction.NoOp	"CWDE"	(+'98') #
Instruction.NoOp	"CWD"	('66',+'99') #
Instruction.NoOp	"HLT"	(+'F4') #
Instruction.NoOp	"IRET"	(+'CF') #
Instruction.NoOp	"LODSB"	(+'AC') #
Instruction.NoOp	"LODSD"	(+'AD') #
Instruction.NoOp	"MOVSB"	(+'A4') #
Instruction.NoOp	"MOVSD"	(+'A5') #
Instruction.NoOp	"NOP"	(+'90') #
Instruction.NoOp	"POPA"	(+'61') #
Instruction.NoOp	"POPF"	(+'9D') #
Instruction.NoOp	"PUSHA"	(+'60') #
Instruction.NoOp	"PUSHF"	(+'9C') #
Instruction.NoOp	"RDMSR"	('0F',+'32') #
Instruction.NoOp	"REP"	(+'F3') #
Instruction.NoOp	"REPE"	(+'F3') #
Instruction.NoOp	"REPNE"	(+'F2') #
Instruction.NoOp	"RETF"	(+'CB') #
Instruction.NoOp	"RET"	(+'C3') #
Instruction.NoOp	"SCASB"	(+'AE') #
Instruction.NoOp	"SCASD"	(+'AF') #
Instruction.NoOp	"STC"	(+'F9') #
Instruction.NoOp	"STD"	(+'FE') #
Instruction.NoOp	"STI"	(+'FB') #
Instruction.NoOp	"STOSB"	(+'AA') #
Instruction.NoOp	"STOSD"	(+'AB') #
Instruction.NoOp	"SYSENTER"	('0F',+'34') #
Instruction.NoOp	"SYSEXIT"	('0F',+'35') #
Instruction.NoOp	"WRMSR"	('0F',+'30') #
Instruction.NoOp	"XLAT"	(+'D7') #


-- Single Register Instructions Code Table --

Instruction.RegOp	"DEC"	(+'48') :- not Config.Mode AMD64 #
Instruction.RegOp	"INC"	(+'40') :- not Config.Mode AMD64 #
Instruction.RegOp	"POP"	(+'58') #
Instruction.RegOp	"PUSH"	(+'50') #


-- Single Reg/Mem Instructions Code Table --

  -- Instruction.RmOp <inst> <cc> <d>
  --   generates: cc[+1 for word operation] mod/d/RM
Instruction.RmOp	"DEC"	(+'FE') 1 #
Instruction.RmOp	"INC"	(+'FE') 0 #
Instruction.RmOp	"NEG"	(+'F6') 3 #
Instruction.RmOp	"NOT"	(+'F6') 2 #
Instruction.RmOp	"POP"	(+'8F') 0 #
Instruction.RmOp	"PUSH"	(+'FF') 6 #


-- Single Immediate Instructions Code Table --

Instruction.ImmOp	"PUSH"	'68' #


-- Accumulator & Immediate Instructions Code Table --

  -- Instruction.AccImmOp <inst> <cc> generates cc[+1] mod/reg/RM
Instruction.AccImmOp	"ADC"	(+'14') #
Instruction.AccImmOp	"ADD"	(+'04') #
Instruction.AccImmOp	"CMP"	(+'3C') #
Instruction.AccImmOp	"OR"	(+'0C') #
Instruction.AccImmOp	"SUB"	(+'2C') #
Instruction.AccImmOp	"TEST"	(+'A8') #
Instruction.AccImmOp	"XOR"	(+'34') #


-- Reg/Mem & Immediate Instructions Code Table --

  -- Instruction.RmImmOp <inst> <cc> <d> generates cc[+1] mod/d/RM imm
Instruction.RmImmOp	"ADC"	(+'80') 2 #
Instruction.RmImmOp	"ADD"	(+'80') 0 #
Instruction.RmImmOp	"CMP"	(+'80') 7 #
Instruction.RmImmOp	"MOV"	(+'C6') 0 #
Instruction.RmImmOp	"OR"	(+'80') 1 #
Instruction.RmImmOp	"SUB"	(+'80') 5 #
Instruction.RmImmOp	"TEST"	(+'F6') 0 #
Instruction.RmImmOp	"XOR"	(+'80') 6 #


-- Reg/Mem & Reg Instructions Code Table --

  -- Instruction.RmRegOp <inst> <cc> generates cc[+3][+1] mod/reg/RM
Instruction.RmRegOp	"ADC"	(+'10') #
Instruction.RmRegOp	"ADD"	(+'00') #
Instruction.RmRegOp	"CMP"	(+'38') #
Instruction.RmRegOp	"LEA"	(+'8B') # -- Will add the bit 1 prefix
Instruction.RmRegOp	"MOV"	(+'88') #
Instruction.RmRegOp	"OR"	(+'08') #
Instruction.RmRegOp	"SUB"	(+'28') #
Instruction.RmRegOp	"TEST"	(+'84') #
Instruction.RmRegOp	"XOR"	(+'30') #


-- Near Jump Instructions Table --

Instruction.NearJumpOp "CALL"	('E8') #
Instruction.NearJumpOp "JMP"	('E9') #


-- Conditional Branch Instructions Table --

  -- Instruction.BranchOp <inst> <tttn>
Instruction.BranchOp	"JA"	7 #
Instruction.BranchOp	"JAE"	3 #
Instruction.BranchOp	"JB"	2 #
Instruction.BranchOp	"JBE"	6 #
Instruction.BranchOp	"JC"	2 #
Instruction.BranchOp	"JE"	4 #
Instruction.BranchOp	"JG"	15 #
Instruction.BranchOp	"JGE"	13 #
Instruction.BranchOp	"JL"	12 #
Instruction.BranchOp	"JLE"	14 #
Instruction.BranchOp	"JNA"	6 #
Instruction.BranchOp	"JNAE"	2 #
Instruction.BranchOp	"JNB"	3 #
Instruction.BranchOp	"JNBE"	7 #
Instruction.BranchOp	"JNC"	3 #
Instruction.BranchOp	"JNE"	5 #
Instruction.BranchOp	"JNG"	14 #
Instruction.BranchOp	"JNGE"	12 #
Instruction.BranchOp	"JNL"	13 #
Instruction.BranchOp	"JNLE"	15 #
Instruction.BranchOp	"JNO"	1 #
Instruction.BranchOp	"JNP"	12 #
Instruction.BranchOp	"JNS"	9 #
Instruction.BranchOp	"JNZ"	5 #
Instruction.BranchOp	"JO"	0 #
Instruction.BranchOp	"JP"	10 #
Instruction.BranchOp	"JPE"	10 #
Instruction.BranchOp	"JPO"	11 #
Instruction.BranchOp	"JS"	8 #
Instruction.BranchOp	"JZ"	4 #


-- Instructions With 1-Word Operand Sizes Table --

	-- Generator would not add bit 0 for these
Instruction.WordSizeOps "LEA" #
Instruction.WordSizeOps "PUSH" #
Instruction.WordSizeOps "POP" #


-- Instructions With Different Operand Sizes Table --

Instruction.DiffSizeOps	"MOVSX" #
Instruction.DiffSizeOps	"MOVZX" #
Instruction.DiffSizeOps	"SAL" #
Instruction.DiffSizeOps	"SAR" #
Instruction.DiffSizeOps	"SHL" #
Instruction.DiffSizeOps	"SHR" #
Instruction.DiffSizeOps	"RCL" #
Instruction.DiffSizeOps	"RCR" #
Instruction.DiffSizeOps	"ROL" #
Instruction.DiffSizeOps	"ROR" #


-- Data Definition Instructions --

Instruction.Data "D8" 1 #
Instruction.Data "D16" 2 #
Instruction.Data "D32" 4 #
Instruction.Data "D64" 8 #


-- Specific Instructions Generation (Not really table...) --

Instruction.TwoOps "IMUL" #

Generate.Instruction ("IMUL" .op1 (GR .size .r)) .size
  ($ $ ('0F',+'AF') $ .mod .r .RM .S .I .B .disp $) :- !
  Config.WordSize .size,
  ModRM.Calc .op1 (.mod .RM .S .I .B .disp) #


-- Scale Encoding in SIB --

Scale.Index 1 0 #
Scale.Index 2 1 #
Scale.Index 4 2 #
Scale.Index 8 3 #


-- General Registers --

Register "AL"	(GR 1 0 ) #
Register "CL"	(GR 1 1 ) #
Register "DL"	(GR 1 2 ) #
Register "BL"	(GR 1 3 ) #
Register "AH"	(GR 1 (NOREX 4)) :- Config.Mode AMD64 ! # -- Must be coded
Register "CH"	(GR 1 (NOREX 5)) :- Config.Mode AMD64 ! # --  without REX prefix
Register "DH"	(GR 1 (NOREX 6)) :- Config.Mode AMD64 ! #
Register "BH"	(GR 1 (NOREX 7)) :- Config.Mode AMD64 ! #
Register "SPL"	(GR 1 (REX 4)) :- Config.Mode AMD64 # -- And with REX prefix...
Register "BPL"	(GR 1 (REX 5)) :- Config.Mode AMD64 #
Register "SIL"	(GR 1 (REX 6)) :- Config.Mode AMD64 #
Register "DIL"	(GR 1 (REX 7)) :- Config.Mode AMD64 #
Register "AH"	(GR 1 4 ) #
Register "CH"	(GR 1 5 ) #
Register "DH"	(GR 1 6 ) #
Register "BH"	(GR 1 7 ) #
Register "R8B"	(GR 1 8 ) :- Config.Mode AMD64 #
Register "R9B"	(GR 1 9 ) :- Config.Mode AMD64 #
Register "R10B"	(GR 1 10) :- Config.Mode AMD64 #
Register "R11B"	(GR 1 11) :- Config.Mode AMD64 #
Register "R12B"	(GR 1 12) :- Config.Mode AMD64 #
Register "R13B"	(GR 1 13) :- Config.Mode AMD64 #
Register "R14B"	(GR 1 14) :- Config.Mode AMD64 #
Register "R15B"	(GR 1 15) :- Config.Mode AMD64 #

Register "AX"	(GR 2 0 ) #
Register "CX"	(GR 2 1 ) #
Register "DX"	(GR 2 2 ) #
Register "BX"	(GR 2 3 ) #
Register "SP"	(GR 2 4 ) #
Register "BP"	(GR 2 5 ) #
Register "SI"	(GR 2 6 ) #
Register "DI"	(GR 2 7 ) #
Register "R8W"	(GR 2 8 ) :- Config.Mode AMD64 #
Register "R9W"	(GR 2 9 ) :- Config.Mode AMD64 #
Register "R10W"	(GR 2 10) :- Config.Mode AMD64 #
Register "R11W"	(GR 2 11) :- Config.Mode AMD64 #
Register "R12W"	(GR 2 12) :- Config.Mode AMD64 #
Register "R13W"	(GR 2 13) :- Config.Mode AMD64 #
Register "R14W"	(GR 2 14) :- Config.Mode AMD64 #
Register "R15W"	(GR 2 15) :- Config.Mode AMD64 #

Register "EAX"	(GR 4 0 ) #
Register "ECX"	(GR 4 1 ) #
Register "EDX"	(GR 4 2 ) #
Register "EBX"	(GR 4 3 ) #
Register "ESP"	(GR 4 4 ) #
Register "EBP"	(GR 4 5 ) #
Register "ESI"	(GR 4 6 ) #
Register "EDI"	(GR 4 7 ) #
Register "R8D"	(GR 4 8 ) :- Config.Mode AMD64 #
Register "R9D"	(GR 4 9 ) :- Config.Mode AMD64 #
Register "R10D"	(GR 4 10) :- Config.Mode AMD64 #
Register "R11D"	(GR 4 11) :- Config.Mode AMD64 #
Register "R12D"	(GR 4 12) :- Config.Mode AMD64 #
Register "R13D"	(GR 4 13) :- Config.Mode AMD64 #
Register "R14D"	(GR 4 14) :- Config.Mode AMD64 #
Register "R15D"	(GR 4 15) :- Config.Mode AMD64 #

Register "RAX"	(GR 8 0 ) #
Register "RCX"	(GR 8 1 ) #
Register "RDX"	(GR 8 2 ) #
Register "RBX"	(GR 8 3 ) #
Register "RSP"	(GR 8 4 ) #
Register "RBP"	(GR 8 5 ) #
Register "RSI"	(GR 8 6 ) #
Register "RDI"	(GR 8 7 ) #
Register "R8"	(GR 8 8 ) :- Config.Mode AMD64 #
Register "R9"	(GR 8 9 ) :- Config.Mode AMD64 #
Register "R10"	(GR 8 10) :- Config.Mode AMD64 #
Register "R11"	(GR 8 11) :- Config.Mode AMD64 #
Register "R12"	(GR 8 12) :- Config.Mode AMD64 #
Register "R13"	(GR 8 13) :- Config.Mode AMD64 #
Register "R14"	(GR 8 14) :- Config.Mode AMD64 #
Register "R15"	(GR 8 15) :- Config.Mode AMD64 #


-- Segment Registers --

Register "ES"	(SR 0) #
Register "CS"	(SR 1) #
Register "SS"	(SR 2) #
Register "DS"	(SR 3) #
Register "FS"	(SR 4) #
Register "GS"	(SR 5) #


-- Control Registers --

Register "CR0"	(CR 0) #
Register "CR2"	(CR 2) #
Register "CR3"	(CR 3) #
Register "CR4"	(CR 4) #
